package logica;

import java.util.ArrayList;
import java.util.List;

import entidades.Ambiente;

public class Arvore {

	private static final int CUSTO_GIRO = 1;
	private static final int CUSTO_GIRO_DUPLO = 2;
	private final static int CUSTO_EXPLOSAO = 3;
	private final static int CUSTO_PASSO = 1;

	private ArrayList <Vertice> vertices;
	private Ambiente calabouco;

	public Ambiente getCalabouco() {
		return calabouco;
	}

	public List<Vertice> getVertices() {
		return vertices;
	}

	public void setMatrizDeAdjacentes(ArrayList<Vertice> vertices) {
		this.vertices = vertices;
	}

	private int larguraAmbiente;
	private int alturaAmbiente;

	public Arvore(Ambiente calabouco) {
		this.calabouco = calabouco;
		this.larguraAmbiente = calabouco.LARGURA;
		this.alturaAmbiente = calabouco.ALTURA;
		this.vertices = new ArrayList<Vertice>();
	}

	public void adicionaVertice(Vertice vertice) {
		vertices.add(vertice);
	}

//	private void criaVertices() {
//		for (int x = 0; x < alturaAmbiente; x++) {
//			for (int y = 0; y < larguraAmbiente; y++) {
//				Vertice vertice = new Vertice(new Posicao(x, y));
//				vertices.add(vertice);
//			}
//		}
//	}
	
	public void atualizaCustoAdjacente(Vertice atual, Vertice adjacente) {
		Celula celulaAdjacente = this.getCalabouco().getMatriz()[adjacente.getPosicao().getX()][adjacente.getPosicao().getY()];
		double custo = 0;
		double custoGiro = 0;//getValorDoGiro(adjacente.getPosicao(), adjacente.getPosicao());
		if (celulaAdjacente instanceof Catre) {
			custo = CUSTO_EXPLOSAO + CUSTO_PASSO + custoGiro;
		} else {
			custo = CUSTO_PASSO + custoGiro;
		}
		adjacente.setCusto(custo);
	}

	public List<Vertice> getAdjacentes(Vertice vertice, boolean adicionaALista) {
		List<Vertice> adjacentes = new ArrayList<Vertice>();
		int x = vertice.getPosicao().getX();
		int y = vertice.getPosicao().getY();

		// Verifica Norte
		if (x - 1 >= 0) {
			Vertice adjacente = new Vertice(new Posicao(x - 1, y));
			adicionaAdjacente(adjacentes, adjacente, vertice, adicionaALista);
		}

		// Verifica Oeste
		if (y - 1 >= 0) {
			Vertice adjacente = new Vertice(new Posicao(x, y - 1));
			adicionaAdjacente(adjacentes, adjacente, vertice, adicionaALista);
		}

		// Verifica Leste
		if (y + 1 <= larguraAmbiente - 1) {
			Vertice adjacente = new Vertice(new Posicao(x, y + 1));
			adicionaAdjacente(adjacentes, adjacente, vertice, adicionaALista);
		}

		// Verifica Sul
		if (x + 1 <= alturaAmbiente - 1) {
			Vertice adjacente = new Vertice(new Posicao(x + 1, y));
			adicionaAdjacente(adjacentes, adjacente, vertice, adicionaALista);
		}
		return adjacentes;
	}

	private void adicionaAdjacente(List<Vertice> adjacentes, Vertice adjacente, Vertice pai, boolean adicionaALista) {
		Vertice adjacenteExistente = getVerticeDaArvore(adjacente);
		if (adjacenteExistente == null){
			if (adicionaALista){
				vertices.add(adjacente);
				atualizaCustoAdjacente(pai, adjacente);
				adjacente.setNivel(pai.getNivel() + 1);
			}
			adjacentes.add(adjacente);
		} else {
			adjacentes.add(adjacenteExistente);
			atualizaCustoAdjacente(pai, adjacenteExistente);
		}
	}

	private Vertice getVerticeDaArvore(Vertice vertice) {
		for (Vertice v : vertices) {
			if (v.equals(vertice))
				return v;
		}
		return null;
	}

	public Vertice[] getVerticesIniciais() {
		Vertice[] verticesIniciais = new Vertice[vertices.size()];
		for (int i = 0; i < verticesIniciais.length; i++) {
			verticesIniciais[i] = vertices.get(i);
		}
		return verticesIniciais;
	}
}
